﻿using System;
using System.IO;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Navigation;
using Microsoft.Win32;
using System.Collections.ObjectModel;
using System.Xml.Serialization;
using CourseSync.CourseManager.Manager;
using CourseSync.CourseManager.Entity;
using System.Collections.Generic;
using System.Threading;
using CourseSync.LibFetcher.Fetcher;
using System.Windows.Threading;
using System.Configuration;

namespace MainWindow
{
	public partial class PhotoBookViewer
	{
		private List<Course> _cList;
		private Dictionary<string, List<CFile>> _allFileList;
		private List<Course> _pList;
		private List<CFile> _cfList;
		private List<Course> _syncList;

		private bool _syncRunning;
		private Thread _viewThread;
		private Thread _syncThread;

		public PhotoBookViewer()
		{
			Manager.Initialize();
			Manager.Config.Username = MainWindow.Properties.Settings.Default.UserName;
			Manager.Config.Password = MainWindow.Properties.Settings.Default.Password;
			Manager.Config.Dir = MainWindow.Properties.Settings.Default.SavePath;
			Manager.Config.PrintDir = MainWindow.Properties.Settings.Default.PrintPath;
			Manager.Config.SizeLimit = MainWindow.Properties.Settings.Default.SizeLimit;
			_cList = new List<Course>();
			_pList = new List<Course>();
			_allFileList = new Dictionary<string, List<CFile>>();
			_syncList = new List<Course>();
			_syncRunning = false;

			this.InitializeComponent();
			_viewThread = new Thread(new ThreadStart(Sync));
			_viewThread.IsBackground = true;
			_viewThread.Start();

			statusTextBlock.Text = string.Format("Current User: {0}, File Size Limit: {1} MBytes, Download to {2}.", Manager.Config.Username,Manager.Config.SizeLimit,Manager.Config.Dir);
		}


		private void OnExit(object sender, RoutedEventArgs e)
		{
			this.Close();
		}

		private void OnUpdate(object sender, RoutedEventArgs e)
		{
			_allFileList.Clear();
			_cList.Clear();
			_pList.Clear();
			Update();
			if (currentRadioButton.IsChecked.Value)
			{
				courseListView.ItemsSource = _cList;
			}
			else
			{
				courseListView.ItemsSource = _pList;
			}

		}

		private void Update()
		{
			//statusTextBlock.Text = "Initializing ...";

			//statusTextBlock.Text = "Login ...";
			if (Manager.Login())
			{
				//statusTextBlock.Text = "Reading current course list ...";
				_cList = Manager.GetCurrentCourses();

				//statusTextBlock.Text = "Reading past course list ...";
				_pList = Manager.GetPastCourses();

				//statusTextBlock.Text = "Finish course update ...";
			}
			else
			{
				MessageBox.Show("Login failed! Check username/password.");
			}
		}

		private List<CFile> UpdateCourseFile(string course_id)
		{
			if (Manager.Login())
			{
				//statusTextBlock.Text = "Reading course file list ...";
				List<CFile> cf = Manager.GetFiles(course_id);
				//statusTextBlock.Text = "Finish file update ...";
				return cf;
			}
			else
			{
				MessageBox.Show("Login failed! Check username/password.");
				return new List<CFile>();
			}
		}

		private void courseListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
		{
			Course c = (Course)courseListView.SelectedItem;
			if (c == null)
				return;
			List<CFile> cf = null;
			if (_allFileList.ContainsKey(c.CourseId))
			{
				cf = _allFileList[c.CourseId];
			}
			else
			{
				cf = UpdateCourseFile(c.CourseId);
				_allFileList.Add(c.CourseId, cf);
			}
			fileListView.ItemsSource = cf;
		}

		private void updateCurrentButton_Click(object sender, RoutedEventArgs e)
		{
			if (courseListView.SelectedItem == null)
				return;

			Course c = (Course)courseListView.SelectedItem;
			List<CFile> cf = UpdateCourseFile(c.CourseId);
			if (_allFileList.ContainsKey(c.CourseId))
				_allFileList.Remove(c.CourseId);
			_allFileList.Add(c.CourseId, cf);
			fileListView.ItemsSource = cf;
		}

		private void currentRadioButton_Checked(object sender, RoutedEventArgs e)
		{
			if (courseListView != null)
				courseListView.ItemsSource = _cList;
		}

		private void pastRadioButton_Checked(object sender, RoutedEventArgs e)
		{
			if (courseListView != null)
				courseListView.ItemsSource = _pList;
		}

		
		private void Sync()
		{
			while (true)
			{
				List<Downloader> downList = new List<Downloader>();
				downList.AddRange(Manager.FinishList);
				downList.AddRange(Manager.RunningList);
				downList.AddRange(Manager.WaitQueue);
				Downloader dl = null;
				if (Manager.WaitQueue.Count > 0)
					dl = Manager.WaitQueue[0];

				//downListView.ItemsSource = downList;
				this.Dispatcher.Invoke(
				(ThreadStart)delegate
				{
					if (downListView != null)
					{
						downListView.ItemsSource = downList;
						if (dl != null)
							downListView.ScrollIntoView(dl);
					}

				}
				, DispatcherPriority.Normal);
				Thread.Sleep(1000);
			}
		}

		private void StartSync()
		{
			if (_syncRunning)
				return;
			_syncRunning = true;
			foreach (Course c in _syncList)
			{
				//Course c = _cList[0];
				List<CFile> cf = null;
				if (_allFileList.ContainsKey(c.CourseId))
					_allFileList.Remove(c.CourseId);
				cf = UpdateCourseFile(c.CourseId);
				_allFileList.Add(c.CourseId, cf);
				foreach (CFile f in cf)
				{
					Manager.DownloadFile(c, f);
					System.Diagnostics.Debug.WriteLine("Add File: " + f.Name);
					Thread.Sleep(500);
				}
			}
			while (Manager.WaitQueue.Count > 0)
			{
				Thread.Sleep(1000);
			}
			MessageBox.Show("Finish current synchronizing!");
			
			_syncRunning = false;
		}


		private void syncButton_Click(object sender, RoutedEventArgs e)
		{
			if (_syncRunning && MessageBox.Show("i AM synchronizing! You want to stop me?", "Warning", MessageBoxButton.YesNo) != MessageBoxResult.Yes)
				return;

			if (_syncThread != null)
				_syncThread.Abort();
	
			try
			{
				for (int i = 0; i < 3; i++)
				{
					Manager.ResetDownloaders();
				}
				Button b = (Button)sender;
				_syncList.Clear();
				switch (b.Name)
				{
					case "syncSelectedButton":
						Course c = (Course)courseListView.SelectedItem;
						if (c != null)
							_syncList.Add(c);
						break;
					case "syncCurrentButton":
						_syncList.AddRange(_cList);

						break;
					case "syncPastButton":

						_syncList.AddRange(_pList);
						break;
					case "syncAllButton":
						_syncList.AddRange(_cList);
						_syncList.AddRange(_pList);
						break;
					case "stopSyncButton":
						_syncRunning = false;
						return;
						break;
					default:
						_syncList.AddRange(_cList);
						_syncList.AddRange(_pList);
						break;

				}

				_syncThread = new Thread(new ThreadStart(StartSync));
				_syncThread.IsBackground = true;
				_syncThread.Start();

			}
			catch (System.Exception ex)
			{
				if (_syncThread != null)
					_syncThread.Abort();
				_syncRunning = false;
			}

		}

		private void OnConfig(object sender, RoutedEventArgs e)
		{	
			ConfigDialog cdlg = new ConfigDialog();
			cdlg.Username = Manager.Config.Username;
			cdlg.Password = Manager.Config.Password;
			cdlg.SavePath = Manager.Config.Dir;
			cdlg.PrintPath = Manager.Config.PrintDir;
			cdlg.SizeLimit= Manager.Config.SizeLimit;
			bool? re = cdlg.ShowDialog();
			if (re.HasValue && re.Value)
			{
				Manager.Config.Username = cdlg.Username;
				Manager.Config.Password = cdlg.Password;
				Manager.Config.Dir = cdlg.SavePath;
				Manager.Config.PrintDir = cdlg.PrintPath;
				Manager.Config.SizeLimit = cdlg.SizeLimit;
				if (cdlg.Remember)
				{
					try
					{
						MainWindow.Properties.Settings.Default.UserName = cdlg.Username;
						MainWindow.Properties.Settings.Default.Password = cdlg.Password;
						MainWindow.Properties.Settings.Default.SavePath = cdlg.SavePath;
						MainWindow.Properties.Settings.Default.PrintPath = cdlg.PrintPath;
						MainWindow.Properties.Settings.Default.SizeLimit = cdlg.SizeLimit;
						MainWindow.Properties.Settings.Default.Save();
					}
					catch
					{
						MessageBox.Show("I can't read the config file!");
					}
				}
			}
		}

		private void stopCurSyncButton_Click(object sender, RoutedEventArgs e)
		{
			Downloader dl = (Downloader)downListView.SelectedItem;
			if (dl == null)
				return;
			dl.Abort();
		}
	}
}